/*
 * VertexBuffer.cpp
 *
 *  Created on: 2011/06/23
 *      Author: naoki
 */

#include "StdAfx.h"
#include "Graphics/src/VertexBufferImpl.h"

namespace NTEngine {
namespace Graphics {

const int VertexBuffer::Impl::VERTEX_SIZES[] = {
	sizeof( Vertex ),
	sizeof( BlendingVertex ),
};

void setInputLayoutVertex() {
	const unsigned char* offset = 0;
	glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, sizeof( Vertex ), offset );
	offset += sizeof( Math::Vector4 );
	glVertexAttribPointer( 1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( Vertex ), offset );
	offset += sizeof( unsigned );
	glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, sizeof( Vertex ), offset );
	offset += sizeof( Math::Vector2 );
	glVertexAttribPointer( 3, 3, GL_FLOAT, GL_FALSE, sizeof( Vertex ), offset );
}

void setInputLayoutBlendingVertex() {
	const unsigned char* offset = 0;
	glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, sizeof( BlendingVertex ), offset );
	offset += sizeof( Math::Vector4 );
	glVertexAttribPointer( 1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( BlendingVertex ), offset );
	offset += sizeof( unsigned );
	glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, sizeof( BlendingVertex ), offset );
	offset += sizeof( Math::Vector2 );
	glVertexAttribPointer( 3, 3, GL_FLOAT, GL_FALSE, sizeof( BlendingVertex ), offset );
	offset += sizeof( Math::Vector3 );
	glVertexAttribPointer( 4, 4, GL_FLOAT, GL_FALSE, sizeof( BlendingVertex ), offset );
	offset += sizeof( Math::Vector4 );
	glVertexAttribPointer( 5, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof( BlendingVertex ), offset );
}

const VertexBuffer::Impl::VOID_FUNC VertexBuffer::Impl::SET_INPUT_LAYOUT[] = {
	setInputLayoutVertex,
	setInputLayoutBlendingVertex,
};

VertexBuffer VertexBuffer::create( Xml::ConstElement e ){
	VertexBuffer r;
	r.mImpl = NEW Impl( e );
	return r;
}

VertexBuffer VertexBuffer::create( int vertexNumber, Format fmt, Managed mng ) {
	VertexBuffer ret;
	ret.mImpl = NEW Impl( vertexNumber, fmt, mng );
	return ret;
}

// lock,unlockの特殊化。長いし同じ処理になるのでマクロにした
#define LOCK_UNLOCK_VERTEX_BUFFER( vertex_type, vertex_format ) \
template<> void VertexBuffer::lock( vertex_type** pp ) {\
	ASSERT( pp );\
	HARD_ASSERT( mImpl->mFormat == vertex_format );\
	*pp = static_cast< vertex_type* >( mImpl->lock() );\
}\
template<> void VertexBuffer::unlock( vertex_type** pp ) {\
	ASSERT( pp );\
	HARD_ASSERT( vertex_format == mImpl->mFormat );\
	mImpl->unlock();\
	*pp = 0;\
}

LOCK_UNLOCK_VERTEX_BUFFER( Vertex, VertexBuffer::FORMAT_VERTEX )
LOCK_UNLOCK_VERTEX_BUFFER( BlendingVertex, VertexBuffer::FORMAT_BLENDINGVERTEX )
#undef LOCK_UNLOCK_VERTEX_BUFFER

const char* VertexBuffer::name() const {
	return mImpl->mName;
}

int VertexBuffer::vertexNumber() const {
	return mImpl->mVertexNumber;
}

VertexBuffer::Format VertexBuffer::format() const {
	return mImpl->mFormat;
}

VertexBuffer::Managed VertexBuffer::managed() const {
	return mImpl->mManaged;
}

void VertexBuffer::updateSkin( const Matrix3x4* matrixPallete, int matrixNumber ) {

}

VertexBuffer::VertexBuffer( const Impl* ) : mImpl( 0 ) {  //ヌルポからの自動生成
}

#define TYPE VertexBuffer
#include "NTEngine/Base/Impl/ReferenceCounterTemplate.h"

} // namespace Graphics
} // namespace NTEngine
